home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.06 Jun 90 / Timing Files / Timer.a < prev    next >
Encoding:
Text File  |  1989-02-07  |  7.2 KB  |  285 lines  |  [TEXT/MPS ]

  1. *-------------------------------------------------------------------------------
  2. *
  3. *    IMPLEMENTATION MODULE Timer
  4. *
  5. *    (Timer mit Auflösung von 1.3 µs)
  6. *
  7. *
  8. *    Version 1 / O. Maquelin / 5-Jan-89
  9. *
  10. *
  11. *    *** Nur für Macintosh II ***
  12. *
  13. *-------------------------------------------------------------------------------
  14.  
  15.     MACHINE    MC68020        ; nur auf Macintosh II lauffähig
  16.     MC68881    PRECISION=X
  17.  
  18. HWNonPortable EQU    1        ; für HardWareEqu
  19. onMac    EQU    0
  20. onNuMac    EQU    1
  21.  
  22.  
  23.     INCLUDE    'HardwareEqu.a'    ; VIA Adressen
  24.     INCLUDE    'SysEqu.a'        ; Variable Ticks
  25.  
  26.  
  27.     EXPORT    Timer: DATA
  28.     EXPORT    (InitTimer, StartTimer, StopTimer, MsValue): CODE
  29.  
  30.  
  31. *    ClkPerTick = 13024
  32.  
  33. ClkPerTick    EQU    13024        ; Zyklen pro Tick (16.663 ms)
  34.  
  35.  
  36. *    TimeRec = RECORD hi, lo: LONGCARD END
  37.  
  38. TimeRec    RECORD    0
  39. hi    DS.L    1        ; High Word
  40. lo    DS.L    1        ; Low Word
  41.     ENDR
  42.  
  43.  
  44. *    MsPerClock: LONGREAL
  45. *    Compensation: LONGCARD
  46.  
  47. Timer    RECORD    EXPORT,DECR        ; VARs von Module Timer
  48. MsPerClock    DC.X    "1.2766E-3"        ; 1.2766 µs pro Clock
  49. Compensation DC.L    27        ; 27 Zyklen Kompensation
  50. TotComp_lo    DC.L    0        ; Total zu kompensieren
  51. TotComp_hi    DC.L    0
  52.     ENDR
  53.  
  54.  
  55. *-------------------------------------------------------------------------------
  56. *
  57. *    PROCEDURE InitTimer %PASCAL (VAR t: TimeRec)
  58. *
  59. *    (Initialisieren einer TimeRec Variable)
  60. *
  61. *
  62. *    Die Felder hi und lo werden auf 0 initialisiert.
  63. *
  64. *-------------------------------------------------------------------------------
  65.  
  66. InitTimer    PROC    EXPORT        ; Von Modula-2 aus aufgerufen
  67.  
  68.     MOVE.L    (SP)+,A0        ; Returnadresse lesen
  69.     MOVE.L    (SP)+,A1        ; Adresse von t lesen
  70.  
  71.     CLR.L    TimeRec.hi(A1)    ; hi und lo löschen
  72.     CLR.L    TimeRec.lo(A1)
  73.  
  74.     JMP    (A0)        ; Zurück zum Caller
  75.     ENDPROC
  76.  
  77.  
  78. *-------------------------------------------------------------------------------
  79. *
  80. *    PROCEDURE GetTime (VAR hi [D0], lo [D1]: LONGCARD)
  81. *
  82. *    (Zeit in Maschinenzyklen bestimmen)
  83. *
  84. *
  85. *    GetTime gibt die momentane Zeit in Maschinenzyklen (1.2766 µs) in
  86. *    den Registern D0 und D1 zurück. Die Zeit wird anhand der globalen
  87. *    Variable Ticks und des Zustands des VIA 2 Bausteins bestimmt.
  88. *
  89. *-------------------------------------------------------------------------------
  90.  
  91. GetTime    PROC    ENTRY        ; Nur lokal aufgerufen
  92.  
  93.     MOVE.L    #VBase2,A1        ; Basisadresse von VIA 2 laden
  94.     
  95.     MOVE    SR,-(SP)        ; Disable Interrupts
  96.     ORI    #$0700,SR
  97.     
  98.     MOVE.B    vT1CH(A1),D1    ; High Byte von Timer 1 lesen
  99.     MOVE.B    vBufB(A1),D0    ; Zustand von Pseudo-VBL lesen
  100.     MOVE.B    vT1C(A1),D2        ; Low Byte von Timer 1 lesen
  101.     ROR.W    #8,D2
  102.     MOVE.B    vT1CH(A1),D2    ; High Byte von Timer 1 lesen
  103.     
  104.     CMP.B    D1,D2        ; Wenn beide High Bytes gleich
  105.     BEQ.S    @1        ; sind, ist der Wert gültig,
  106.                 ; sonst Lesevorgang wiederholen
  107.  
  108.     MOVE.B    vBufB(A1),D0    ; Zustand von Pseudo-VBL lesen
  109.     MOVE.B    vT1C(A1),D2        ; Low Byte von Timer 1 lesen
  110.     ROR.W    #8,D2
  111.     MOVE.B    vT1CH(A1),D2    ; High Byte von Timer 1 lesen
  112.     
  113. @1    ROR.W    #8,D2        ; Low und High Byte vertauschen
  114.     
  115.     MOVEQ    #7,D1        ; Erste Phase des Ticks?
  116.     BTST.L    D1,D0
  117.     BNE.S    @2    
  118.     ADD.W    #ClkPerTick/2,D2    ; Nein, Zyklenzahl korrigieren
  119.  
  120. @2    MOVE.L    Ticks,D1        ; Ticks lesen
  121.     
  122.     MOVE    (SP)+,SR        ; Enable Interrupts
  123.     
  124.     CMP.W    #ClkPerTick-10,D2    ; Nulldurchgang erwischt?
  125.     BLE.S    @3
  126.     ADDQ    #1,D1        ; Ja, Ticks korrigieren
  127.     
  128. @3    MULU.L    #ClkPerTick,D0:D1    ; Ticks mit ClkPerTick mult.
  129.     EXT.L    D2        ; und Zyklenzahl subtrahieren
  130.     SUB.L    D2,D1
  131.     MOVEQ    #0,D2        ; Extend Bit addieren
  132.     SUBX.L    D2,D0
  133.     
  134.     RTS            ; Zurück zum Caller
  135.     ENDPROC
  136.  
  137.  
  138. *-------------------------------------------------------------------------------
  139. *
  140. *    PROCEDURE StartTimer %PASCAL (VAR t: TimeRec)
  141. *
  142. *    (Timer t starten)
  143. *
  144. *
  145. *    Die momentane Zeit in Maschinenzyklen wird vom Wert in t
  146. *    subtrahiert. Nach StartTimer sollte der Wert von t deshalb nicht
  147. *    gelesen werden.
  148. *
  149. *-------------------------------------------------------------------------------
  150.  
  151. StartTimer    PROC    EXPORT        ; Von Modula-2 aus aufgerufen
  152.     
  153.     MOVEC    CACR,D0        ; Cache ausschalten
  154.     MOVE.L    D0,A0        ; Cachezustand retten
  155.     AND.B    #$FE,D0
  156.     MOVEC    D0,CACR
  157.     
  158.     MOVE.L    Timer.Compensation,D0    ; Totale Kompensation inkrement.
  159.     ADD.L    D0,Timer.TotComp_lo
  160.     BCC.S    @1        ; Ist ein Übertrag entstanden?
  161.     ADDQ    #1,Timer.TotComp_hi    ; Ja, high Word inkrementieren
  162.     
  163. @1    JSR    GetTime        ; Momentane Zeit bestimmen
  164.                 ; -> kommt in Register D0, D1
  165.     
  166.     MOVE.L    4(SP),A1        ; Adresse von t lesen
  167.     
  168.     MOVE.L    Timer.TotComp_hi,D2    ; Komp. von Zeit subtrahieren
  169.     SUB.L    Timer.TotComp_lo,D1    ; Low Word addieren
  170.     SUBX.L    D2,D0        ; High Word addieren
  171.     
  172.     MOVE.L    TimeRec.hi(A1),D2    ; Resultat von t subtrahieren
  173.     SUB.L    D1,TimeRec.lo(A1)    ; Low Word subtrahieren
  174.     SUBX.L    D0,D2        ; High Word subtrahieren...
  175.     MOVE.L    D2,TimeRec.hi(A1)    ; und zurückschreiben
  176.     
  177.     MOVEC    A0,CACR        ; Cache wieder einschalten    
  178.     
  179.     MOVE.L    (SP)+,A0        ; Returnadresse lesen
  180.     ADDQ    #4,SP
  181.     JMP    (A0)        ; Zurück zum Caller
  182.     ENDPROC
  183.  
  184.  
  185. *-------------------------------------------------------------------------------
  186. *
  187. *    PROCEDURE StopTimer %PASCAL (VAR t: TimeRec)
  188. *
  189. *    (Timer t stoppen)
  190. *
  191. *
  192. *    Die momentane Zeit in Maschinenzyklen wird zum Wert in t
  193. *    addiert. Nach dem Aufruf von StartTimer und StopTimer enthält t
  194. *    somit den Wert: <alter Wert> - <Startzeit> + <Stoppzeit>.
  195. *
  196. *-------------------------------------------------------------------------------
  197.  
  198. StopTimer    PROC    EXPORT        ; Von Modula-2 aus aufgerufen
  199.  
  200.     MOVEC    CACR,D0        ; Cache ausschalten
  201.     MOVE.L    D0,A0        ; Cachezustand retten
  202.     AND.B    #$FE,D0
  203.     MOVEC    D0,CACR
  204.     
  205.     MOVE.L    Timer.Compensation,D0    ; Totale Kompensation inkrement.
  206.     ADD.L    D0,Timer.TotComp_lo
  207.     BCC.S    @1        ; Ist ein Übertrag entstanden?
  208.     ADDQ    #1,Timer.TotComp_hi    ; Ja, high Word inkrementieren
  209.     
  210. @1    JSR    GetTime        ; Momentane Zeit bestimmen
  211.                 ; -> kommt in Register D0, D1
  212.     
  213.     MOVE.L    4(SP),A1        ; Adresse von t lesen
  214.  
  215.     MOVE.L    Timer.TotComp_hi,D2    ; Komp. von Zeit subtrahieren
  216.     SUB.L    Timer.TotComp_lo,D1    ; Low Word addieren
  217.     SUBX.L    D2,D0        ; High Word addieren
  218.     
  219.     MOVE.L    TimeRec.hi(A1),D2    ; Resultat zu t addieren
  220.     ADD.L    D1,TimeRec.lo(A1)    ; Low Word addieren
  221.     ADDX.L    D0,D2        ; High Word addieren...
  222.     MOVE.L    D2,TimeRec.hi(A1)    ; und zurückschreiben
  223.     
  224.     MOVEC    A0,CACR        ; Cache wieder einschalten    
  225.     
  226.     MOVE.L    (SP)+,A0        ; Returnadresse lesen
  227.     ADDQ    #4,SP
  228.     JMP    (A0)        ; Zurück zum Caller
  229.     ENDPROC
  230.  
  231.  
  232. *-------------------------------------------------------------------------------
  233. *
  234. *    PROCEDURE MsValue %PASCAL (VAR t: TimeRec): LONGREAL
  235. *
  236. *    (Wert des Timers in Millisekunden)
  237. *
  238. *
  239. *    Diese Prozedur gibt den Wert des Timers in Millisekunden zurück:
  240. *
  241. *    MsValue = (t.hi * 4294967296 + t.lo) * MsPerClock
  242. *
  243. *-------------------------------------------------------------------------------
  244.  
  245. MsValue    PROC    EXPORT        ; Von Modula-2 aus aufgerufen
  246.  
  247.     MOVE.L    (SP)+,A0        ; Returnadresse lesen
  248.     MOVE.L    (SP)+,A1        ; Adresse von t lesen
  249.     
  250.     FMOVEM    FP0/FP1,-(SP)    ; Register FP0 und FP1 retten
  251.     
  252.     MOVE.L    TimeRec.lo(A1),D1    ; Inhalt von t in Register laden
  253.     MOVE.L    TimeRec.hi(A1),D0
  254.     BPL.S    @1        ; Negativer Wert?
  255.     NEG.L    D1        ; Ja, Wert negieren
  256.     NEGX.L    D0
  257.  
  258. @1    FMOVE.L    D0,FP0        ; FP0 := t.hi
  259.     FMOVE.L    D1,FP1        ; FP1 := t.lo
  260.     TST.L    D1        ; Wert von D1 negativ?
  261.     BPL.S    @2
  262.     FADD.X    Bit32,FP1        ; Ja, Wert korrigieren
  263.     
  264. @2    FMUL.X    Bit32,FP0        ; FP0 := FP0 * 4294967296
  265.     FADD    FP1,FP0        ; FP0 := FP0 + FP1
  266.     FMUL.X    Timer.MsPerClock,FP0    ; FP0 := FP0 * MsPerClock
  267.     
  268.     TST.L    TimeRec.hi(A1)    ; Wert war negativ?
  269.     BPL.S    @3
  270.     FNEG.X    FP0        ; Ja, Resultat negieren
  271.     
  272. @3    FMOVE.X    FP0,24(SP)        ; Resultat auf Stack schreiben
  273.     
  274.     FMOVEM    (SP)+,FP0/FP1    ; Register wiederherstellen
  275.     
  276.     JMP    (A0)        ; Zurück zum Caller
  277.     
  278. Bit32    DC.X    "4294967296.0"    ; Konstante für die Konversion
  279.     ENDPROC
  280.  
  281.  
  282. *-------------------------------------------------------------------------------
  283.  
  284.     END
  285.